﻿using System;
using System.Threading;

namespace TiaoTiaoCode.Common.ClassEntities
{
    public sealed class TiaoTiaoSimpleHybirdLock : IDisposable
    {
        #region IDisposable Support
        private bool disposedValue = false; // 要检测冗余调用

        void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    //  释放托管状态(托管对象)。
                }

                disposedValue = true;
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }
        #endregion

        /// <summary>
        /// 基元用户模式构造同步锁
        /// </summary>
        private int m_waiters = 0;

        /// <summary>
        /// 基元内核模式构造同步锁
        /// </summary>
        private readonly Lazy<AutoResetEvent> m_waiterLock = new Lazy<AutoResetEvent>(() => new AutoResetEvent(false));

        /// <summary>
        /// 获取锁
        /// </summary>
        public void Enter()
        {
            Interlocked.Increment(ref simpleHybirdLockCount);
            if (Interlocked.Increment(ref m_waiters) == 1) return;      // 用户锁可以使用的时候，直接返回，第一次调用时发生
                                                                        // 当发生锁竞争时，使用内核同步构造锁
            Interlocked.Increment(ref simpleHybirdLockWaitCount);

            m_waiterLock.Value.WaitOne();
        }

        /// <summary>
        /// 离开锁
        /// </summary>
        public void Leave()
        {
            Interlocked.Decrement(ref simpleHybirdLockCount);
            if (Interlocked.Decrement(ref m_waiters) == 0) return;     // 没有可用的锁的时候

            Interlocked.Decrement(ref simpleHybirdLockWaitCount);

            m_waiterLock.Value.Set();
        }

        /// <summary>
        /// 获取当前锁是否在等待当中
        /// </summary>
        public bool IsWaitting => m_waiters != 0;

        #region Static Value

        private static long simpleHybirdLockCount = 0;      // 当前总的锁的进入次数
        private static long simpleHybirdLockWaitCount = 0;  // 当前锁的等待的次数，此时已经开始竞争了

        /// <summary>
        /// 获取当前总的所有进入锁的信息<br />
        /// Get the current total information of all access locks
        /// </summary>
        public static long SimpleHybirdLockCount => simpleHybirdLockCount;

        /// <summary>
        /// 当前正在等待的锁的统计信息，此时已经发生了竞争了
        /// </summary>
        public static long SimpleHybirdLockWaitCount => simpleHybirdLockWaitCount;

        #endregion
    }
}
